
#include "hpsc.h"
#include <QtDebug>
#include <QSettings>
#include <iostream>
#include <QApplication>
#include "hpsccommadthread.h"

CHPSC::CHPSC(QString serPort,QObject *parent)
	:QObject(parent),
	m_serial(NULL),
	m_currSrc(NOSRC),
    m_query(READ_STAT)
{
	
	QSettings settings("../../gss.conf",QSettings::IniFormat);
	if(serPort.isEmpty())
	 m_serPort = settings.value("Serial_Ports/HPSC/port").toString();
	else m_serPort = serPort;
	qDebug()<<"serial port:"<<m_serPort;
	if(!m_serial)
		m_serial = new QextSerialPort(m_serPort);
	if(!m_serial) qWarning("HPSC could not allocate serial port object") ;
	else {
        //TODO: get these values from the conf file
        
		m_serial->setBaudRate(BAUD9600);
		m_serial->setDataBits(DATA_8);
		m_serial->setParity(PAR_NONE);
		m_serial->setStopBits(STOP_1);
		m_serial->setFlowControl(FLOW_XONXOFF);
//		m_serial->setName(port);
		if(!m_serial->open())
			qWarning()<<"HPSC coulnd not open serial port "<<m_serPort;
		else qWarning()<<"HPSC opened "<<m_serPort;
	}
	m_commandLoop = new HPSCCommandThread(m_serial);
	qDebug()<<"init timer";
	m_pollTimer = new QTimer(this);
	//connect(m_pollTimer,SIGNAL(timeout()),this,SLOT(pollStatus()));
    connect(m_commandLoop,SIGNAL(sig_pollNext()),this,SLOT(pollStatus()));
	connect(m_commandLoop,SIGNAL(sig_readout(QString)),this,SLOT(readHpsc(QString)));
	connect(m_commandLoop,SIGNAL(sig_readoutV(int,QString)),this,SLOT(readHpscV(int,QString)));
	connect(m_commandLoop,SIGNAL(sig_readoutA(int,QString)),this,SLOT(readHpscA(int,QString)));
	//m_pollTimer->start(27);
    QTimer::singleShot(0,this,SLOT(pollStatus()));
}

CHPSC::~CHPSC()
{
}


/*!
    \fn CHPSC::sendCommand(QString cmd)
 */
void CHPSC::sendCommand(QString cmd,long usWait)
{
	qDebug()<<" CHPSC::sendCommand(QString cmd,long usWait)+++++++++++++"<<cmd;
	m_commandLoop->postCommand(cmd,usWait);
}


/*!
    \fn CHPSC::pollErrRegister()
 */
// void CHPSC::pollStatus()
// {
// 	
// //	qDebug()<<"CHPSC::pollStatus()";
// 	quint16 newErr=0;
// 	float fvolt=0.0,famper=0.0;
// 	quint8 chVolt[50], chAmper[50];
// 	QString strVolt,strAmper;
// 	int bytes;
//   //while(1)
//   //{     
//  	 //m_commandLoop->executeCommand("STAT:QUES:COND1?",50000);
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("STAT:QUES:COND1?"),30000)));
// 	 //usleep(50000); //wait for command execution
//      newErr = hpscReadout().toShort();
//      if(newErr != 0)
//      {
//       //m_hpscErrReg = newErr;
//       printf("REGERR: hex:%x",newErr);
//       emit sig_hpscError(1,newErr);
// 	  //qApp->processEvents();
//      }
//     
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("*TRG"),30000)));
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:VOLT1?"),20000)));
// 	fvolt = hpscReadoutV(1).toFloat();
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:CURR1?"),20000)));
// 	famper = hpscReadoutA(1).toFloat();
// //	qDebug()<<"HPSC about to emit readout:"<<1<<" "<<fvolt<<" "<<famper;
//     emit sig_hpscReadout(1,fvolt,famper);
//     fvolt=0.0;
//     famper=0.0;
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:VOLT2?"),20000)));
// 	fvolt = hpscReadoutV(2).toFloat();
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:CURR2?"),20000)));
// 	famper = hpscReadoutA(2).toFloat();
//     emit sig_hpscReadout(2,fvolt,famper);
//     fvolt=0.0;
//     famper=0.0;
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:VOLT3?"),20000)));
// 	fvolt = hpscReadoutV(3).toFloat();
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:CURR3?"),20000)));
// 	famper = hpscReadoutA(3).toFloat();
//     emit sig_hpscReadout(3,fvolt,famper);
//     fvolt=0.0;
//     famper=0.0;
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:VOLT4?"),20000)));
// 	fvolt = hpscReadoutV(4).toFloat();
// 	QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:CURR4?"),20000)));
// 	famper = hpscReadoutA(4).toFloat();
//     emit sig_hpscReadout(4,fvolt,famper);
// 
//   
// 	newErr=0;
// 	fvolt=0.0;
// 	famper=0.0;
// 	memset(chVolt,0,50);
// 	memset(chAmper,0,50);
// 	strVolt = "0.0";
// 	strAmper = "0.0";
// 	bytes = -1;
//   //}
// }
void CHPSC::pollStatus()
{
    
//  qDebug()<<"CHPSC::pollStatus()";
    quint16 newErr=0;
    float fvolt=0.0,famper=0.0;
    quint8 chVolt[50], chAmper[50];
    QString strVolt,strAmper;
    int bytes;
    
    switch(m_query)
    {
        case READ_STAT:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("STAT:QUES:COND1?"),15000)));
            m_query = READ_CHANS;
            break;
        case READ_CHANS:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("*TRG"),15000)));
            m_query = V1;
            break;
        case V1:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:VOLT1?"),15000)));
            m_query = A1;
            break;
        case A1:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:CURR1?"),15000)));
            m_query = V2;
            break;
        case V2:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:VOLT2?"),15000)));
            m_query = A2;
            break;
        case A2:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:CURR2?"),15000)));
            m_query = V3;
            break;
        case V3:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:VOLT3?"),15000)));
            m_query = A3;
            break;
        case A3:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:CURR3?"),15000)));
            m_query = V4;
            break;
        case V4:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:VOLT4?"),15000)));
            m_query = A4;
            break;
        case A4:
            QCoreApplication::postEvent(m_commandLoop,new HPSCEventBase(HPSCMEAS,QPair<QString,long>(QString("MEAS:CURR4?"),15000)));
            m_query = READ_STAT;
            break;
    }
}

/*!
    \fn CHPSC::readHpsc()
 */
void CHPSC::readHpscV(int src,QString readout)
{
	//qDebug()<<"CHPSC::readHpsc getting:"<<readout;
	switch(src)
	{
		case 1: 
            m_readoutV1 = readout;
            emit sig_hpscReadoutV(src,m_readoutV1.toFloat());
			break;
		case 2: 
            m_readoutV2 = readout;
            emit sig_hpscReadoutV(src,m_readoutV2.toFloat());
			break;
		case 3: 
            m_readoutV3 = readout;
            emit sig_hpscReadoutV(src,m_readoutV3.toFloat());
			break;
		case 4: 
            m_readoutV4 = readout;
            emit sig_hpscReadoutV(src,m_readoutV4.toFloat());
	}

}

void CHPSC::readHpscA(int src,QString readout)
{
	//qDebug()<<"CHPSC::readHpsc getting:"<<readout;
	switch(src)
	{
		case 1: 
            m_readoutA1 = readout;
            emit sig_hpscReadoutA(src,m_readoutA1.toFloat());
		break;
		case 2: 
            m_readoutA2 = readout;
            emit sig_hpscReadoutA(src,m_readoutA2.toFloat());
		break;
		case 3: 
            m_readoutA3 = readout;
            emit sig_hpscReadoutA(src,m_readoutA3.toFloat());
		break;
		case 4: 
            m_readoutA4 = readout;
            emit sig_hpscReadoutA(src,m_readoutA4.toFloat());
	}

}



/*!
    \fn CHPSC::hpscReadout()
 */
QString CHPSC::hpscReadoutV(int src)
{
    switch(src)
	{
		case 1: return m_readoutV1;
		case 2: return m_readoutV2;
		case 3: return m_readoutV3;
		case 4: return m_readoutV4;
	}
}

QString CHPSC::hpscReadoutA(int src)
{
	switch(src)
	{
		case 1: return m_readoutA1;
		case 2: return m_readoutA2;
		case 3: return m_readoutA3;
		case 4: return m_readoutA4;
	}
    
    return QString("");
}

/*!
    \fn CHPSC::eventLoop()
 */
HPSCCommandThread * CHPSC::eventLoop()
{
    return m_commandLoop;
}




/*!
    \fn CHPSC::hpscReadout(QString readout)
 */
void CHPSC::readHpsc(QString readout)
{
    m_readout = readout;
    //if the last query was READ_STAT (so current m_query = READ_CHANS), check for error message
    if(m_query == READ_CHANS && readout.toShort() != 0)
    {
        printf("REGERR: hex:%x",readout.toShort());
        emit sig_hpscError(1,readout.toShort());
    }
}


/*!
    \fn CHPSC::hpscReadout()
 */
QString CHPSC::hpscReadout()
{
    return m_readout;
}
